%{
extern "C"
{
        int expparse(void);
        int explex(void);
}

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void experror(const char *str)
{
	fprintf(stderr,"error: %s\n",str);
}

int expwrap()
{
	return 1;
}

extern char* exp_input_ptr;

#include "RoutePlanner.h"
#include "Stack.h"

bool res = 0;
BooleanStack bstack;
CharsStack opstack;

bool RoutePlanner::eval(string condition) {
    exp_input_ptr = strdup(condition.data());
    expparse();

    return res;
}

%}

%token PO PC NOT;

%union
{
	char* word;
        char character;
        float number;
        int (*boop2)(float, float);
        int (*comp2)(int, int);
}

%token <word> WORD;
%token <character> CHAR
%token <number> NUMBER;
%token <number> BOOL;
%token <boop2> COP;
%token <comp2> BOP;

%%

commands: boolean_expression {
    if(bstack.size() > 0) {
        res = bstack[0];
        if(bstack.size() > 1) {
            experror("Boolean expression seems to be not well-formed!\n");
        }
    } else {
        res = 0;
    }

    bstack.reset();
    opstack.reset();
};

boolean_expression: BOOL {
    bstack.push($1);
} | NOT BOOL {
    bstack.push(!$2);
} | NUMBER COP NUMBER {
    bstack.push($2($1, $3));
} | PO NUMBER COP NUMBER PC {
    bstack.push($3($2, $4));
} | NOT PO NUMBER COP NUMBER PC {
    bstack.push(!$4($3, $5));
} | boolean_expression BOP boolean_expression {
    if(bstack.size() >= 2) {
        bstack.push($2(*bstack.pop(), *bstack.pop()));
    } else {
        printf("Upps, less than two bools on stack\n");
    }
};